home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1996 July: Mac OS SDK / Dev.CD Jul 96 SDK / Dev.CD Jul 96 SDK1.toast / Development Kits (Disc 1) / OpenDoc Development Framework / ODF & Cyberdog / ODFCyberLibrary / Sources / SLCyPart.cpp < prev    next >
Encoding:
Text File  |  1996-04-22  |  11.6 KB  |  325 lines  |  [TEXT/MPS ]

  1. //-----------------------------------------------------------------------------
  2. //    SLCyPart.cpp
  3. //    Implementation of FW_OCyberPartExtension.
  4. //    Redirects all methods into C callbacks provided by the client.
  5. //    
  6. //    Copyright (c) 1995 - 1996 by Apple Computer, Inc., all rights reserved.
  7. //-----------------------------------------------------------------------------
  8.  
  9. #define ODF_FW_OCyberPartExtension_Class_Source
  10. #include <SLCyPart.xih>
  11.  
  12. #include <MemMgr.h>
  13.  
  14. //-----------------------------------------------------------------------------
  15. // Since we have a SOM interface, we have to make sure we don't try to
  16. // throw any C++ exceptions out of here; we need to catch them and convert
  17. // them into SOM exceptions.
  18. // Note that while the C callbacks *must* not throw exception and will set
  19. // ev->_major, all other method calls, including the _parent_ macros, will
  20. // invoke SOMCHKEXCEPT and therefore may throw exceptions.
  21. //-----------------------------------------------------------------------------
  22.  
  23. static const char FW_kInvalidException[] = "Unknown Exception!"; 
  24.  
  25. #define BEGIN_SOM_SAFETY            \
  26.     FW_TRY                            \
  27.     {
  28.  
  29. #define END_SOM_SAFETY                \
  30.     }                                \
  31.     FW_CATCH_BEGIN                    \
  32.     FW_CATCH_REFERENCE(FW_XException, exception)\
  33.     {                                \
  34.         FW_SetException(ev, exception);\
  35.     }                                \
  36.     FW_CATCH_EVERYTHING()            \
  37.     {                                \
  38.         FW_DEBUG_MESSAGE(FW_kInvalidException);\
  39.         FW_SetEvError(ev, kODErrUndefined);\
  40.     }                                \
  41.     FW_CATCH_END
  42.  
  43. //-----------------------------------------------------------------------------
  44. // We should not do anything if our base part has been removed (IsValid).
  45. // Also make sure we have a callback struct and callback.
  46. //-----------------------------------------------------------------------------
  47.  
  48. #define SAFECALL(RESULT,METHOD,PARAMETERS)    \
  49.     if (somSelf->IsValid(ev)                 \
  50.             && somThis->fCallbacks             \
  51.             && somThis->fCallbacks->METHOD)    \
  52.         (RESULT (somThis->fCallbacks->METHOD) PARAMETERS, SOMCHKEXCEPT)
  53.  
  54. /*-----------------------------------------------------------------------------
  55.     SOM Subclass of CyberPartExtension
  56.     
  57.     These methods generally call C methods which have been exported from a
  58.     client. These C methods must not throw C++ exceptions. Most of these
  59.     methods here don't call C++ methods or somSelf methods and so do not
  60.     need to guard against exceptions being thrown via SOMCHKEXCEPT.
  61. -----------------------------------------------------------------------------*/
  62.  
  63. SOM_Scope void  SOMLINK SLCyPart__Release (ODF_FW_OCyberPartExtension *somSelf, Environment *ev)
  64. {
  65.     BEGIN_SOM_SAFETY
  66.     
  67.     ODBoolean isOwned = somSelf->IsValid (ev);
  68.     ODF_FW_OCyberPartExtension_parent_CyberPartExtension_Release(somSelf,ev);
  69.     
  70.     if (!isOwned && somSelf->GetRefCount(ev) == 0)
  71.         delete somSelf;
  72.     
  73.     END_SOM_SAFETY
  74. }
  75.  
  76. SOM_Scope void  SOMLINK 
  77. SLCyPart__OpenCyberItem(ODF_FW_OCyberPartExtension *somSelf, Environment* ev, CyberItem* item, ODPart* openerPart, ParameterSet* openParams)
  78. {
  79.     ODF_FW_OCyberPartExtensionData *somThis = ODF_FW_OCyberPartExtensionGetData(somSelf);
  80.     BEGIN_SOM_SAFETY
  81.     
  82.     // The base class implements the default behavior, which is to call 
  83.     // somSelf->SetCyberItem(item), and then to either tell the openerPart
  84.     // (if it is not kODNULL) to open the associated base part, or to tell
  85.     // the base part to open itself.
  86.     // Developers may call inherited.
  87.     
  88.     // mlanett 4/18/96 In order to make it possible for developer to call inherited, the
  89.     // call to ODF_FW_OCyberPartExtension_parent_CyberPartExtension_OpenCyberItem has been
  90.     // moved to DefaultOpenCyberItem. FW_MCyberPart calls this by default. Developers
  91.     // can override, and by calling inherited from C++, will get the actual inherited SOM 
  92.     // functionality. See FW_MCyberPart::HandleOpenCyberItem.
  93.     ODBoolean callInherited = false;
  94.     
  95.     SAFECALL(,openCyberItem,(ev, somThis->fCallbacks, item, openerPart, openParams));
  96.     
  97.     if (callInherited)
  98.         ODF_FW_OCyberPartExtension_parent_CyberPartExtension_OpenCyberItem(somSelf,ev,item,openerPart,openParams);
  99.     
  100.     END_SOM_SAFETY
  101. }
  102.  
  103. SOM_Scope void  SOMLINK 
  104. SLCyPart__SetCyberItem(ODF_FW_OCyberPartExtension *somSelf, Environment* ev, CyberItem* item, ParameterSet* openParams)
  105. {
  106.     ODF_FW_OCyberPartExtensionData *somThis = ODF_FW_OCyberPartExtensionGetData(somSelf);
  107.     
  108.     // This method is called to notify the extension that it is now 
  109.     // responsible for displaying a new CyberItem. Developers will 
  110.     // typically override this method to notify the associated part.
  111.     // Base class releases the old CyberItem (if any) and acquires the new
  112.     // CyberItem. Subsequent calls to GetCyberItem will return this item.
  113.     
  114.     ODF_FW_OCyberPartExtension_parent_CyberPartExtension_SetCyberItem(somSelf,ev,item,openParams);
  115.     
  116.     SAFECALL(,setCyberItem,(ev, somThis->fCallbacks, item, openParams));
  117. }
  118.  
  119. SOM_Scope ODBoolean  SOMLINK 
  120. SLCyPart__CanShowCyberItem(ODF_FW_OCyberPartExtension *somSelf, Environment *ev,
  121.         CyberItem* item)
  122. {
  123.     ODF_FW_OCyberPartExtensionData *somThis = ODF_FW_OCyberPartExtensionGetData(somSelf);
  124.     
  125.     // Returns kODTrue if this CyberPart is displaying the specified item. 
  126.     // Base class checks whether the item is equal to the value of 
  127.     // GetCyberItem(). Note that in some cases developers may wish to use a 
  128.     // less stringent test. For example, a web browser may return kODTrue 
  129.     // if the item that is passed is a link to a location on that same page 
  130.     // that it is displaying. In this case the URL of the item passed in is 
  131.     // not the same as the URL of current page, but it is contained in that 
  132.     // window.
  133.     
  134.     // This is like an object equality test. x == y is true if x and y
  135.     // are the same object, or if they are similar objects. So, even if the
  136.     // base class returns false (not equal) we still need to test for
  137.     // similarity. Obviously if it returns true then we don't need to
  138.     // test further.
  139.     
  140.     // I think this method is rather badly named.
  141.     
  142.     ODBoolean isSimilar = ODF_FW_OCyberPartExtension_parent_CyberPartExtension_CanShowCyberItem(somSelf,ev,item);
  143.     if (!isSimilar)
  144.         SAFECALL(isSimilar=,canShowCyberItem,(ev, somThis->fCallbacks, item));
  145.     
  146.     return isSimilar;
  147. }
  148.  
  149. SOM_Scope void  SOMLINK 
  150. SLCyPart__ShowCyberItem(ODF_FW_OCyberPartExtension *somSelf, Environment* ev, CyberItem* item)
  151. {
  152.     ODF_FW_OCyberPartExtensionData *somThis = ODF_FW_OCyberPartExtensionGetData(somSelf);
  153.     
  154.     // Tells the part to display the given CyberItem. This differs from 
  155.     // SetCyberItem in that the extension has already indicated (through 
  156.     // CanShowCyberItem or GetCyberItemWindow) that it is already 
  157.     // displaying a cyberitem equal to (or, for example, on the same page 
  158.     // as) the item parameter.
  159.     // Developers must not call inherited.
  160.     
  161.     SAFECALL(,showCyberItem,(ev, somThis->fCallbacks, item));
  162. }
  163.  
  164. SOM_Scope ODWindow*  SOMLINK 
  165. SLCyPart__GetCyberItemWindow (ODF_FW_OCyberPartExtension *somSelf, Environment* ev, CyberItem* item)
  166. {
  167.     ODF_FW_OCyberPartExtensionData *somThis = ODF_FW_OCyberPartExtensionGetData(somSelf);
  168.     ODWindow* window = kODNULL;
  169.     BEGIN_SOM_SAFETY
  170.     
  171.     // Returns the ODWindow (if any) in which this CyberPart is displaying 
  172.     // the specified item. This is useful e.g. when the client wants to 
  173.     // bring an existing window to the front rather than opening a new 
  174.     // window. GetCyberItemWindow should use the same algorithm as in 
  175.     // CanShowCyberItem method to determine whether an item is displayed in 
  176.     // a window.
  177.     
  178.     ODBoolean isShowingSimilar;
  179.         isShowingSimilar = somSelf->CanShowCyberItem (ev, item);
  180.     
  181.     if (isShowingSimilar)
  182.         SAFECALL(window=,getCyberItemWindow,(ev, somThis->fCallbacks, item));
  183.     
  184.     END_SOM_SAFETY
  185.     return window;
  186. }
  187.  
  188. SOM_Scope ODBoolean  SOMLINK 
  189. SLCyPart__IsCyberItemSelected(ODF_FW_OCyberPartExtension *somSelf, Environment* ev, ODFrame* frame)
  190. {
  191.     ODF_FW_OCyberPartExtensionData *somThis = ODF_FW_OCyberPartExtensionGetData(somSelf);
  192.     ODBoolean isAnySelected = false;
  193.     BEGIN_SOM_SAFETY
  194.     
  195.     SAFECALL(isAnySelected=,isCyberItemSelected,(ev, somThis->fCallbacks, frame));
  196.     
  197.     END_SOM_SAFETY
  198.     return isAnySelected;
  199. }
  200.  
  201. SOM_Scope void  SOMLINK 
  202. SLCyPart__AcquireSelectedCyberItems(ODF_FW_OCyberPartExtension *somSelf, Environment* ev, ODFrame* frame, CyberItemList* cyberItems)
  203. {
  204.     // XXX should change this to pass an STL list?
  205.     // Note: If I do it has to be exception-safe.
  206.     ODF_FW_OCyberPartExtensionData *somThis = ODF_FW_OCyberPartExtensionGetData(somSelf);
  207.     BEGIN_SOM_SAFETY
  208.     
  209.     SAFECALL(,acquireSelectedCyberItems,(ev, somThis->fCallbacks, frame, cyberItems));
  210.     
  211.     END_SOM_SAFETY
  212. }
  213.  
  214. SOM_Scope ODBoolean  SOMLINK 
  215. SLCyPart__IsURLSelected(ODF_FW_OCyberPartExtension *somSelf, Environment* ev, ODFrame* frame)
  216. {
  217.     ODF_FW_OCyberPartExtensionData *somThis = ODF_FW_OCyberPartExtensionGetData(somSelf);
  218.     ODBoolean isSelected = FALSE;
  219.     BEGIN_SOM_SAFETY
  220.     
  221.     SAFECALL(isSelected=,isURLSelected,(ev, somThis->fCallbacks, frame));
  222.     
  223.     END_SOM_SAFETY
  224.     return isSelected;
  225. }
  226.  
  227. SOM_Scope char*  SOMLINK 
  228. SLCyPart__GetSelectedURL(ODF_FW_OCyberPartExtension *somSelf, Environment *ev,
  229.         ODFrame* frame)
  230. {
  231.     ODF_FW_OCyberPartExtensionData *somThis = ODF_FW_OCyberPartExtensionGetData(somSelf);
  232.     char* urld = kODNULL;
  233.     BEGIN_SOM_SAFETY
  234.     
  235.     FW_CString surl;
  236.     SAFECALL(,getSelectedURL,(ev, somThis->fCallbacks, frame, surl));
  237.     
  238.     // Note: this code has been arranged so it does not throw any C++ exceptions.
  239.     FW_ByteCount size = surl.GetByteLength();
  240.     if (size) {
  241.         urld = (char*) ::MMAllocate (size + 1);
  242.         if (urld) {
  243.             const char* privates = surl.RevealBuffer();
  244.             memcpy (urld, privates, size);
  245.             urld[size] = 0;
  246.         }
  247.         else
  248.             FW_SetException (ev, kODErrOutOfMemory);
  249.     }
  250.     
  251.     END_SOM_SAFETY
  252.     
  253.     return urld;
  254. }
  255.  
  256. SOM_Scope ODBoolean  SOMLINK 
  257. SLCyPart__HandleCommand(ODF_FW_OCyberPartExtension *somSelf, Environment *ev,
  258.         long commandSuite,
  259.         long commandID,
  260.         ODFrame* frame,
  261.         void* commandData)
  262. {
  263.     ODF_FW_OCyberPartExtensionData *somThis = ODF_FW_OCyberPartExtensionGetData(somSelf);
  264.     ODBoolean wasHandled = false;
  265.     BEGIN_SOM_SAFETY
  266.     
  267.     // Intended as an extensibility mechanism for Cyber parts where clients 
  268.     // can send commands to the part/extension. The function result 
  269.     // indicates whether or not the command was handled.
  270.     // Cyberdog defines some commands in Cyberdog.h. The commandCreator 
  271.     // associated with Cyberdogs commands is kCyberdogCreator.
  272.     // Developers may call inherited.
  273.     
  274.     // mlanett 4/18/96 see comment for OpenCyberItem. Removed call to inherited. See FW_MCyberPart::HandleCyberCommand.
  275.     ODBoolean callInherited = false;
  276.     
  277.     SAFECALL(wasHandled=,handleCommand,(ev, somThis->fCallbacks, commandSuite, commandID, frame, commandData));
  278.     if (callInherited)
  279.         wasHandled |= ODF_FW_OCyberPartExtension_parent_CyberPartExtension_HandleCommand (somSelf,ev,commandSuite,commandID,frame,commandData);
  280.     
  281.     END_SOM_SAFETY
  282.     return wasHandled;
  283. }
  284.  
  285. SOM_Scope void  SOMLINK 
  286. SLCyPart__SetCallbacks(ODF_FW_OCyberPartExtension *somSelf, Environment *ev,
  287.         FW_HCyberPartInterfaceCallbacks callbacks)
  288. {
  289.     // Note: No exception handling here.
  290.     FW_UNUSED(ev);
  291.     
  292.     ODF_FW_OCyberPartExtensionData *somThis = ODF_FW_OCyberPartExtensionGetData(somSelf);
  293.     somThis->fCallbacks = callbacks;
  294. }
  295.  
  296. SOM_Scope void  SOMLINK SLCyPart__DefaultOpenCyberItem(ODF_FW_OCyberPartExtension *somSelf, Environment *ev,
  297.         CyberItem* item,
  298.         ODPart* openerPart,
  299.         ParameterSet* openParams)
  300. {
  301.     BEGIN_SOM_SAFETY
  302.     
  303.     // This method enabled us to call "inherited" OpenCyberItem from the C++ class.
  304.     ODF_FW_OCyberPartExtension_parent_CyberPartExtension_OpenCyberItem(somSelf,ev,item,openerPart,openParams);
  305.     
  306.     END_SOM_SAFETY
  307. }
  308.  
  309. SOM_Scope ODBoolean  SOMLINK SLCyPart__DefaultHandleCommand(ODF_FW_OCyberPartExtension *somSelf, Environment *ev,
  310.         long commandCreator,
  311.         long commandID,
  312.         ODFrame* frame,
  313.         void* commandData)
  314. {
  315.     ODBoolean handled = FALSE;
  316.     BEGIN_SOM_SAFETY
  317.     
  318.     // This method enabled us to call "inherited" HandleCommand from the C++ class.
  319.     handled = ODF_FW_OCyberPartExtension_parent_CyberPartExtension_HandleCommand (somSelf,ev,commandCreator,commandID,frame,commandData);
  320.     
  321.     END_SOM_SAFETY
  322.     return handled;
  323. }
  324.  
  325.